﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Yichat.MicroService.Model
{
    public class DistributeionCacheEntry<TValue> : IDistributeionCacheEntry<TValue>
    {
        public DistributeionCacheEntry(string key, TValue value, TimeSpan? slidingExpiration = null, DateTimeOffset? absoluteExpiration = null)
        {
            this.Key = key;
            this.Value = value;
            this.CreatedUtc = DateTime.UtcNow;
            this.LastAccessUtc = DateTime.UtcNow;

            if (slidingExpiration.HasValue || absoluteExpiration.HasValue)
            {
                if (absoluteExpiration.HasValue)
                {
                    this.CacheExpireStategy = CacheExpireStategy.AbsoluteExpiration;
                    this.AbsoluteExpiration = absoluteExpiration;
                }
                else
                {
                    this.CacheExpireStategy = CacheExpireStategy.SlidingExpiration;
                    this.SlidingExpiration = slidingExpiration;
                }
            }
            else
            {
                this.CacheExpireStategy = CacheExpireStategy.NeverExpiration;
            }
        }

        public string Key { get; private set; }

        public TValue Value { get; private set; }

        public DateTime CreatedUtc { get; set; }

        public CacheExpireStategy CacheExpireStategy { get; set; }

        public DateTimeOffset? AbsoluteExpiration { get; private set; }

        public TimeSpan? SlidingExpiration { get; private set; }

        public DateTime LastAccessUtc { get; set; }

        public bool IsExpired
        {
            get
            {
                if (this.CacheExpireStategy == CacheExpireStategy.NeverExpiration)
                {
                    return false;
                }
                else if (this.CacheExpireStategy == CacheExpireStategy.AbsoluteExpiration
                    && this.AbsoluteExpiration.HasValue)
                {
                    return this.AbsoluteExpiration < DateTimeOffset.Now;
                }
                else if (this.CacheExpireStategy == CacheExpireStategy.SlidingExpiration
                    && this.SlidingExpiration.HasValue)
                {
                    return DateTime.UtcNow > LastAccessUtc + SlidingExpiration;
                }
                else
                {
                    return false;
                }
            }
        }
    }
}
